--[[
Add some copyright information here.
--]]

GenieList = AceLibrary('AceAddon-2.0'):new('AceConsole-2.0',
                                           'AceEvent-2.0',
                                           'AceDB-2.0',
                                           'FuBarPlugin-2.0')

local GenieList = GenieList

-- FuBar handlers.
function GenieList:OnInitialize()
end

function GenieList:OnEnable()
  if not self.db then
    self:RegisterDB('GenieListDB', 'GenieListCharDB')
    self:RegisterDefaults('profile', {
      highlight_item = true,
      show_acquired_items = true,
    })
    self:RegisterDefaults('char', {
      items = {},
    })
  end

	self:RegisterEvent("BAG_UPDATE")
  self:HookItemLinksDB3()
  self:RegisterMenu()

  self:Refresh()
end

function GenieList:OnDisable()
	self:UnregisterAllEvents()
end

-- One-stop function for refresh everything that should be refreshed when
-- internal data changes.
function GenieList:Refresh()
  self:UpdateItemMenu()
  self:Update()
end

function GenieList:BAG_UPDATE()
  if (self:UpdateItems(self.db.char.items)) then
    self:Refresh()
  end
end

function GenieList:GetItemIdFromLink(item_link)
  local _, _, item_id = string.find(item_link, "item:(%-?%d+):")
  return tonumber(item_id)
end

-- Add an item to the wishlist.
function GenieList:AddItem(items, item)
	local item_name, item_link = GetItemInfo(item)
  local item_id = -1
  if (not item_name) then
    -- We allow adding just name item too.
    item_name = item
    item_link = item
  else
    item_id = self:GetItemIdFromLink(item_link)
  end
  if (items[item_name] == nil) then
    items[item_name] = {
      name = item_name,
      id = item_id,
      time = time()
    }
    DEFAULT_CHAT_FRAME:AddMessage(format('Add item: %s', item_link))
  else
    DEFAULT_CHAT_FRAME:AddMessage(format('Item already exists: %s', item_link))
  end
end

-- Removes an item with specified name from the wishlist.
function GenieList:RemoveItem(items, item_name)
  local item = items[item_name]
  items[item_name] = nil
  local _, item_link = GetItemInfo(item.id)
  item_link = item_link or item_name
  DEFAULT_CHAT_FRAME:AddMessage(format('Remove item: %s', item_link))
end

-- Scan through the list of items in bag and bank for acquired items on the
-- wishlist.
function GenieList:UpdateItems(items)
  local updated = false
  local item_name, item
  for item_name, item in pairs(items) do
    if (GetItemCount(item_name, true) > 0) and (not item.acquired) then
      item.acquired = true
      updated = true
      local _, item_link = GetItemInfo(item.id)
      item_link = item_link or item.name
      DEFAULT_CHAT_FRAME:AddMessage(
          format('Congratulations! You\' got item %s', item_link))
    end
  end
  return updated
end

local function ItemCompareByTime(item1, item2)
  -- Acquired items should be at the end of the list.
  if (item1.acquired and (not item2.acquired)) then
    return false
  elseif ((not item1.acquired) and item2.acquired) then
    return true
  end
  -- Both of them have the same acquired status, compare normally.
  if (item1.time and item2.time) then
    return item1.time < item2.time
  else
    -- If time is not available, fall back to alphabetical.
    return item1.name:lower() < item2.name:lower()
  end
end

function GenieList:GetSortedItems(items)
  local sorted_table = {}
  for _, item in pairs(items) do
    sorted_table[#sorted_table + 1] = item
  end
  table.sort(sorted_table, ItemCompareByTime)
  return sorted_table
end
